from pytest import Item
import allure
import time
from dingtalkchatbot.chatbot import DingtalkChatbot

# 本地插件注册
pytest_plugins = ['plugins.pytest_playwright']  # noqa


def pytest_runtest_call(item: Item):  # noqa
    """动态给 allure 添加 feature/title"""
    if item.parent._obj.__doc__:  # noqa
        allure.dynamic.feature(item.parent._obj.__doc__)
    if item.function.__doc__:
        allure.dynamic.title(item.function.__doc__)


def ding_ding_notify(
    access_token,
    secret=None,
    pc_slide=False,
    fail_notice=False,
    title="测试报告",
    text="## 测试报告",
    is_at_all=False,
    at_mobiles=None,
    at_dingtalk_ids=None,
    is_auto_at=True,
    *args,
    **kwargs
):
    """机器人初始化并发送 markdown 消息"""
    webhook = f"https://oapi.dingtalk.com/robot/send?access_token={access_token}"
    ding = DingtalkChatbot(webhook=webhook, secret=secret, pc_slide=pc_slide, fail_notice=fail_notice)

    try:
        result = ding.send_markdown(
            title=title,
            text=text,
            is_at_all=is_at_all,
            at_mobiles=at_mobiles if at_mobiles else [],
            at_dingtalk_ids=at_dingtalk_ids if at_dingtalk_ids else [],
            is_auto_at=is_auto_at,
        )
        return result
    except Exception as e:
        print(f"❌ DingTalk notify failed: {e}")
        return None


# 修改配置（建议用环境变量管理敏感信息）
DING_TALK = {
    "access_token": "4a92104d322b7b8b7a2edeb416aadc875823b76f56d2d78dd94593ef2da8d3eb",
    "title": "测试报告",
    "at_mobiles": ["15926082611"],
    "text": "- 查看报告：[allure报告地址](http://117.72.147.11:8080/job/playwright-testing/allure/)",
}


def pytest_terminal_summary(terminalreporter, exitstatus, config):  # noqa
    """收集测试结果并发送钉钉通知"""
    base_url = config.getoption("--base-url") or config.getini("base_url")
    print(f"------------{base_url}")

    total = terminalreporter._numcollected  # noqa
    if total > 0:
        passed = len([i for i in terminalreporter.stats.get("passed", []) if i.when != "teardown"])
        failed = len([i for i in terminalreporter.stats.get("failed", []) if i.when != "teardown"])
        error = len([i for i in terminalreporter.stats.get("error", []) if i.when != "teardown"])
        successful = len(terminalreporter.stats.get("passed", [])) / terminalreporter._numcollected

        # ✅ 兼容 pytest 新旧版本 (float / Instant)
        start_time = getattr(terminalreporter, "_sessionstarttime", None) \
                     or getattr(terminalreporter, "_session_start", None)
        if start_time:
            try:
                if hasattr(start_time, "timestamp"):  # pytest 8 Instant
                    duration = time.time() - start_time.timestamp()
                elif hasattr(start_time, "monotonic"):  # Instant 支持 monotonic()
                    duration = time.time() - start_time.monotonic()
                elif hasattr(start_time, "total_seconds"):  # timedelta-like
                    duration = (time.time() - start_time).total_seconds()
                else:  # float 旧版本
                    duration = time.time() - float(start_time)
            except Exception:
                duration = 0.0
        else:
            duration = 0.0

        markdown_text = f"""### 执行结果:
- 运行环境: 测试环境
- 运行 base_url: {base_url}
- 持续时间: {duration:.2f} 秒
### 本次运行结果:
- 总用例数: {total}
- 通过用例：{passed}
- 失败用例：{failed}
- 异常用例：{error}
- 通过率：{successful:.2%} \n
"""

        if DING_TALK.get("text"):
            DING_TALK["text"] = markdown_text + DING_TALK["text"]
        else:
            DING_TALK["text"] = markdown_text

        # 发送通知并打印返回结果
        resp = ding_ding_notify(**DING_TALK)
        print("DingTalk notify returned:", resp)
